<template>
  <!-- Ant Design Vue TreeSelect 组件，支持静态或远程树数据 -->
  <a-tree-select v-bind="$attrs" v-model:value="innerValue" :treeData="finalOptions" :loading="loading" />
</template>

<script setup lang="ts">
import { ref, watch, onMounted, computed } from 'vue'

// 定义组件 props 接口
interface Props {
  value?: any // v-model 绑定值
  api?: (_params?: any) => Promise<any> // 可选的远程加载函数
  params?: Record<string, any> // 请求 API 的参数
  options?: any[] // 静态选项列表（优先级更高）
  resultField?: string // 远程结果中的列表字段路径
  labelField?: string // 显示字段（节点 title）
  valueField?: string // 值字段（节点 value / key）
  childrenField?: string // 子节点字段名
  immediate?: boolean // 是否挂载时立即加载
  useRawData?: boolean // 是否使用接口原始数据，不进行字段转换
}

// 定义 props 默认值
const props = withDefaults(defineProps<Props>(), {
  options: () => [], // 默认静态 options 为空数组
  labelField: 'label', // 默认 title 字段为 label
  valueField: 'value', // 默认 key/value 字段为 value
  childrenField: 'children', // 默认子节点字段名
  immediate: true, // 默认挂载立即加载
  useRawData: true // 默认使用原始数据
})

const emit = defineEmits(['update:value']) // 定义 v-model 的事件

const loading = ref(false) // 加载状态
const innerValue = ref(props.value) // 本地 v-model 值
const dynamicOptions = ref<any[]>([]) // 动态加载的数据

// 最终用于渲染的数据源（优先使用 props.options）
const finalOptions = computed(() => {
  return props.options?.length ? props.options : dynamicOptions.value
})

// 请求远程数据
const fetchData = async () => {
  if (!props.api || props.options?.length) return // 如果没有 api 或有静态数据，则不请求
  loading.value = true
  try {
    const res = await props.api(props.params) // 调用 API 拉取数据
    const list = props.resultField ? res[props.resultField] || [] : res
    if (props.useRawData) {
      dynamicOptions.value = Array.isArray(list) ? list : []
    } else {
      // 将数据转换为 tree-select 所需的格式
      const transformTree = (data: any[]): any[] =>
        data.map((item: any) => ({
          title: item[props.labelField], // 显示标题
          value: item[props.valueField], // 节点值
          key: item[props.valueField], // key，避免树结构警告
          children: Array.isArray(item[props.childrenField]) // 递归处理子节点
            ? transformTree(item[props.childrenField])
            : undefined
        }))
      dynamicOptions.value = Array.isArray(list) ? transformTree(list) : []
    }
  } catch (err) {
    console.error('ApiTreeSelect fetch error:', err) // 错误捕获
  } finally {
    loading.value = false // 无论成功与否都结束加载
  }
}

// v-model 外部值变更时同步内部值
watch(
  () => props.value,
  (val) => (innerValue.value = val)
)

// 内部值变化时向外同步
watch(innerValue, (val) => emit('update:value', val))

// 监听参数变化触发数据更新
watch(() => props.params, fetchData, { deep: true })

// 挂载时初始化数据
onMounted(() => {
  if (props.immediate && !props.options?.length) {
    fetchData()
  }
})
</script>
